from qturboframe.lib.report.log import logger
from qturboframe.lib.utils.CustomError.custom_error import CustomError
from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.public_ui.base_element import BaseElement
from qturboframe.public_ui.h_ui.base_table import BaseTable


class SimpleTable(BaseElement):
    '''简单表格操作类'''

    def select_rows(self, table_dict, scroll=False):
        '''
        在当前页根据单元格列名和单元格内容勾选行

        :Args:
         - table_dict: 单元格列名和单元格内容，字典类型，例：{列名1:内容1,列名2:内容2}
         - scroll: 是否自动滚动，默认关闭自动滚动查找功能

        :Example:
         - 例: simple_table.select_rows({'姓名':'admin, manager'})
        '''
        re_checked = 'h-checkbox-checked'
        # 表格数据检查
        key_list = list(table_dict.keys())
        for key in key_list:
            if table_dict.get(key) == '-':
                table_dict.pop(key)
        if not table_dict:
            logger.info('表格查询条件为空，不勾选！')
            return
        elif table_dict.get('_all_'):
            logger.info('当前表格页全选！')
            self.select_all()
        else:
            logger.info('开始表格行号查询')
            # 获取列名列表
            head_table = BaseTable(
                {'xpath': './div/div[@class=\'h-table-header\']/table'}, self._element, self.timeout)
            title_list = head_table.get_title_list()
            row_list = self.__get_row_indexes(title_list, table_dict, scroll)
            logger.info('表格行号查询结束！')
            if len(row_list) == 0:
                raise SeleniumError(CustomError.Error_EQ03007003_Not_Find_Correct_Row,'未找到目标数据行！')
            logger.debug('开始勾选表格行！')
            body_table = BaseTable(
                {'xpath':
                     './div/div[contains(@class, "h-table-body")]/div[@class="h-simple-content"]/table'},
                self._element, self.timeout)
            tr_list = body_table.get_tr_list()
            for row in row_list:
                td = tr_list[int(row - 1)].find_elements_by_attribute('tag name', 'td', timeout=self.timeout)[0]
                span = td.find_element_by_attribute(
                    'css selector', 'label.h-checkbox-wrapper>span.h-checkbox', timeout=self.timeout)
                if re_checked not in span.get_attribute('class').split(' '):
                    span.secure_click()
            logger.info('勾选表格行结束！')

    def select_row(self, table_dict, scroll=False):
        '''
        在当前页根据单元格列名和单元格内容勾选行

        :Args:
         - table_dict: 单元格列名和单元格内容，字典类型，例：{列名1:内容1,列名2:内容2}
         - scroll: 是否自动滚动，默认关闭自动滚动查找功能

        :Example:
         - 例: simple_table.select_row({'姓名':'admin','年龄':'25'}, True)
        '''
        re_checked = 'h-checkbox-checked'
        # 表格数据检查
        key_list = list(table_dict.keys())
        for key in key_list:
            if table_dict.get(key) == '-':
                table_dict.pop(key)
        if not table_dict:
            logger.info('表格查询条件为空！')
            return
        logger.info('开始表格行号查询')
        # 获取列名列表
        head_table = BaseTable(
            {'xpath': './div/div[@class=\'h-table-header\']/table'}, self._element, self.timeout)
        title_list = head_table.get_title_list()
        logger.debug('表格显示列名：' + str(title_list))
        row = self._get_row_index(title_list, table_dict, scroll)
        logger.debug('表格行号查询结束！')
        if row == 0:
            raise SeleniumError(CustomError.Error_EQ03007003_Not_Find_Correct_Row,'未找到目标数据行！')
        logger.debug('开始勾选表格行！')
        body_table = BaseTable(
            {'xpath':
                 './div/div[contains(@class, "h-table-body")]/div[@class="h-simple-content"]/table'},
            self._element, self.timeout)
        tr_list = body_table.get_tr_list()
        td = tr_list[int(row - 1)].find_elements_by_attribute('tag name', 'td', timeout=self.timeout)[0]
        span = td.find_element_by_attribute(
            'css selector', 'label.h-checkbox-wrapper>span.h-checkbox', timeout=self.timeout)
        if re_checked not in span.get_attribute('class').split(' '):
            span.secure_click()
        logger.debug('勾选表格行结束！')

    def get_cell(self, table_dict:dict, title_name, scroll=False):
        '''
        根据单元格列名和单元格内容查找hui表格中所在的单元格

        :Args:
         - table_dict: 列名和内容，字典类型，例：{列名1:内容1,列名2:内容2}
         - title_name: 查找的单元格列名
         - scroll: 是否自动滚动，默认关闭自动滚动查找功能

        :Returns:
            返回查找的单元格

        :Example:
         - 例: cell = simple_table.get_cell({'姓名':'admin', '年龄':'25'}, '工号', True)
        '''
        # 表格数据检查
        key_list = list(table_dict.keys())
        for key in key_list:
            if table_dict.get(key) == '-':
                table_dict.pop(key)
        if not table_dict:
            logger.info('表格查询条件为空！')
            return None
        logger.info('开始表格行号查询')
        # 获取列名列表
        head_table = BaseTable(
            {'xpath': './div/div[@class=\'h-table-header\']/table'}, self._element, self.timeout)
        title_list = head_table.get_title_list()
        logger.debug('表格显示列名：' + str(title_list))
        row = self._get_row_index(title_list, table_dict, scroll)
        logger.debug('表格行号查询结束！')
        if row == 0:
            raise SeleniumError(CustomError.Error_EQ03007003_Not_Find_Correct_Row,'未根据查找条件找到表格行！')
        logger.debug('开始表格单元格查询')
        table_cell = self.__get_cell(title_list, title_name, row)
        logger.debug('单元格查询结束！')
        return table_cell

    def select_all(self):
        '''
        表格行全选

        :Example:
         - 例: simple_table.select_all()
        '''
        re_checked = 'h-checkbox-checked'
        th = self._element.find_elements_by_attribute(
            'xpath', './div/div[@class=\'h-table-header\']/table/thead/tr/th', timeout=self.timeout)[0]
        span = th.find_element_by_attribute(
                'css selector', 'label.h-checkbox-wrapper>span.h-checkbox', timeout=self.timeout)
        if re_checked not in span.get_attribute('class').split(' '):
            span.secure_click()

    def _get_row_index(self, title_list, table_dict, scroll=False):
        key_list = list(table_dict.keys())
        logger.debug('表格查找列名索引：' + str(key_list))
        # 获取指定列内容列表
        body_table = BaseTable(
            {'xpath':
                 './div/div[contains(@class, "h-table-body")]/div[@class="h-simple-content"]/table'},
            self._element, self.timeout)
        # 以输入数据作为索引查找表格行数
        row_list = list()
        for i, key in enumerate(key_list):
            temp_list = list()
            text_list = list()
            if len(text_list) == 0:
                try:
                    title_index = title_list.index(key)
                    logger.debug('第' + str(title_index + 1) + '列，名称：' + key)
                except:
                    logger.debug('表格中没有列名：' + key)
                    continue
                else:
                    text_list = body_table.get_text_list(len(title_list), int(title_index + 1))
            if i == 0:
                rows = len(text_list)
                logger.debug('当前页显示行数：' + str(rows))
                row_list = list(range(1, rows + 1))
            for j in row_list:
                if text_list[j - 1] == table_dict[key]:
                    logger.debug('要查找的内容：' + table_dict[key])
                    logger.debug('第' + str(j) + '行，内容：' + text_list[j - 1])
                    temp_list.append(j)
            row_list = temp_list
            if len(row_list) == 0:
                break
        # 未找到数据行则进行表格翻页
        if len(row_list) > 0:
            return row_list[0]
        else:
            if scroll:
                last_tr = body_table.get_tr_list()[-1]
                last_tr.focus()
                tr_list = last_tr.find_elements_by_attribute(
                    'xpath', './following-sibling::tr', timeout=self.timeout)
                if len(tr_list) > 0:
                    logger.debug("向下滚动查找。")
                    return self._get_row_index(title_list, table_dict, scroll)
                else:
                    return 0
            else:
                return 0

    def __get_row_indexes(self, title_list, table_dict, scroll=False):
        key_list = list(table_dict.keys())
        logger.debug('表格查找列名索引：' + str(key_list))
        # 获取数据表
        body_table = BaseTable(
            {'xpath':
                 './div/div[contains(@class, "h-table-body")]/'
                 'div[@class="h-simple-content"]/table'},
            self._element, self.timeout)
        # 以输入数据作为索引查找表格行数
        row_list = list()
        for i, key in enumerate(key_list):
            text_list = list()
            temp_list = list()
            # 获取指定列内容列表
            if len(text_list) == 0:
                try:
                    title_index = title_list.index(key)
                    logger.debug('第' + str(title_index + 1) + '列，名称：' + key)
                except:
                    logger.debug('表格中没有列名：' + key)
                else:
                    text_list = body_table.get_text_list(len(title_list), int(title_index + 1))
            if i == 0:
                rows = len(text_list)
                logger.debug('当前页显示行数：' + str(rows))
                row_list = list(range(1, rows + 1))
            content_list = table_dict[key].split(',')
            for j in row_list:
                for k in content_list:
                    if text_list[j - 1] == k:
                        logger.debug('要查找的内容：' + k)
                        logger.debug('第' + str(j) + '行，内容：' + text_list[j - 1])
                        temp_list.append(j)
            row_list = temp_list
            if len(row_list) == 0:
                break
        # 判断是否找到数据行
        if len(row_list) > 0:
            return row_list
        else:
            if scroll:
                last_tr = body_table.get_tr_list()[-1]
                last_tr.focus()
                tr_list = last_tr.find_elements_by_attribute(
                    'xpath', './following-sibling::tr', timeout=self.timeout)
                if len(tr_list) > 0:
                    logger.debug("向下滚动查找。")
                    return self.__get_row_indexes(title_list, table_dict, scroll)
                else:
                    return []
            else:
                return []

    def __get_cell(self, title_list, title_name, row):
        table_cell = None
        # 获取数据表格单元格列表
        body_table = BaseTable(
            {'xpath':
                 './div/div[contains(@class, "h-table-body")]/div[@class="h-simple-content"]/table'},
            self._element, self.timeout)
        cell_list = body_table.get_cell_list()
        # 当前表格显示的行数
        rows = len(cell_list) / len(title_list)
        logger.debug(
            '当前页显示行数：{}/{}={}'.format(len(cell_list), len(title_list), rows))
        try:
            title_index = title_list.index(title_name)
            logger.debug('第' + str(title_index + 1) + '列，名称：' + title_name)
        except ValueError:
            raise SeleniumError(CustomError.Error_EQ03007007_Table_Header_Not_Correct,'列名不存在！')
        else:
            cell_index = int(title_index + (len(title_list) * (row - 1)))
            table_cell = cell_list[cell_index]
        return table_cell
